#pragma once

#include "Entity.h"
#include "Input.h"
#include "Timer.h"
#include "DrawnEntity.h"

class Camera :
	public Entity
{
public:
	/* Constructor / Deconstructor */
	Camera(void);
	~Camera(void);

	/* Basic Camera Functions */
	void LookAt(Entity* _focus);
	void SlideTo(Entity* _focus);
	void Zoom(float distance);
	void VelocityZoom(float zoom_acceleration);
	void RotateAround(float angle, VectorXYZ axis);
	void RotateAround(float angle, float XCoord, float YCoord, float ZCoord);

	/* Mouse Camera Functions */
	void SlideTo(MouseState* mouse, std::vector<DrawnEntity*> draw_list);
	void RotateAround(float angle_multiplier, MouseState* mouse);

	/* Convenience Functions */
	void CameraOrbitVertical(float angle);
	void CameraOrbitHorizontal(float angle);
	VectorXYZ LocationToPixel(VectorXYZ location);

	/* Update Routines */
	void Update(); // Called in the physics loop, all the non-opengl stuff
	void PlaceCamera(); // Specifically has to be called before DrawGame() for some reason

	/* Friend Classes */
	friend class Game;

	/* Engine variables */
	float target_fov;
	float near_clipping_distance;
	float far_clipping_distance;

private:
	/* Camera orientation variables */
	float distance;
	Entity* focus;


	/* Camera animation timer */
	Timer camera_clock;

	/* Camera rotation */
	VectorXYZ rotation_velocity;
	void CameraRotationAnimation();

	/* Camera sliding animation */
	bool inMotion;
	Entity* last_focus;
	void CameraSlideAnimation();
	float CameraSmoothing(float fraction);

	/* Camera zoom animation */
	float zoom_speed;
	void CameraZoomAnimation();
};